{
  LW IO -- LightWave Save and Load State

  This unit contains the definition of the structures needed to
  perform I/O from a LightWave server.

  Based on lwio.h which is:
  Copyright 1999, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}


unit LW_IO;

{$mode objfpc}{$H+}

interface

uses
  LW_Types;

const
  {
    Data may be loaded and saved in binary or text files.  Text files
    are often scene files, and binary files are often object files.

    In BINARY mode, the external form contains raw bytes having any
    value from 0 to 255.  Reads and writes are entirely based on the
    number of bytes requested.

    In ASCII mode, all data bytes must be in the extended ASCII range
    of 32 to 255.  Values outside this range are ignored or undefined.
  }
  LWIO_BINARY = 0          ;
  LWIO_ASCII  = 1          ;
  LWIO_OBJECT = LWIO_BINARY;
  LWIO_SCENE  = LWIO_ASCII ;

  LWFILEIOFUNCS_GLOBAL = 'File IO 3';
  LWIO_BINARY_IFF      = $8C0000    ;
  LWIO_BINARY_IFF32    = $8D0000    ;

type
  {
    Blocks of data can be marked with identifiers.  In BINARY mode the
    four-byte ID code is used, and in ASCII mode the string token (which
    should not contain spaces) is used.
  }
  PLWBlockIdent = ^TLWBlockIdent;
  TLWBlockIdent = record
    ID    : TLWID;
    Token : PChar;
  end;

  {
    This structure is used when the server is writing its state to
    the external store.  The 'writeData' is the first argument to all
    the callback functions.

    Write        execute a raw write to the store.  In BINARY mode, the
                 number of bytes indicated by 'len' is written directly to
                 the output.  In ASCII mode the input buffer is treated as
                 a null-terminated string and the length is computed from
                 that.  The string is written with a newline at the end.

    WriteI1      write an array of different sized and typed integers to
    WriteI2      the store.  In BINARY mode the 'n' numbers are written as
    WriteI4      1, 2 or 4 btype elements in "big-endian" (Motorola)
    WriteU1      format.  In ASCII mode, all 'n' numbers are written to a
    WriteU2      single line, the signed values in decimal and the unsigned
    WriteU4      values in hexadecimal.  A newline is written after the
                 list of numbers unless the writing is done inside a leaf
                 block.

    WriteStr     write a null-terminated string to the store.  In ASCII
                 mode the string may be contained in double quotes.

    WriteID      write an identifier token to the store.  In BINARY mode
                 this is the four-byte ID code, while in ASCII mode this
                 is the string token.

    BeginBlk     start a nested data block.  The block is identified by
                 the ID codes defined in the LWBlockIdent, and the 'leaf'
                 flag is true if this block will not contain other blocks.

    EndBlk       end the current data block.

    Depth        return the current block nesting level, where zero means
                 we've entered no blocks.
  }
  PLWSaveState = ^TLWSaveState;
  TLWSaveState = record
    IOMode    : Integer;
    WriteData : Pointer;

    Write    : procedure
               (      Data       : Pointer      ;
                const Buffer     : PChar        ;
                      Length     : Integer      ) ;

    WriteI1  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PChar        ;
                      N          : Integer      ) ;
    WriteI2  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PSmallInt    ;
                      N          : Integer      ) ;
    WriteI4  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PInteger     ;
                      N          : Integer      ) ;
    WriteU1  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PByte        ;
                      N          : Integer      ) ;
    WriteU2  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PWord        ;
                      N          : Integer      ) ;
    WriteU4  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PCardinal    ;
                      N          : Integer      ) ;
    WriteFP  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PSingle      ;
                      N          : Integer      ) ;
    WriteStr : procedure
               (      Data       : Pointer      ;
                const Buffer     : PChar        ) ;
    WriteID  : procedure
               (      Data       : Pointer      ;
                const BlockIdent : PLWBlockIdent) ;

    BeginBlk : procedure
               (      Data       : Pointer      ;
                const BlockIdent : PLWBlockIdent;
                      Leaf       : Integer      ) ;
    EndBlk   : procedure
               (      Data       : Pointer      ) ;
    Depth    : function
               (      Data       : Pointer      ) : Integer;
    WriteDP  : procedure
               (      Data       : Pointer      ;
                const Buffer     : PDouble      ;
                      N          : Integer      ) ;
  end;

  {
    This structure is used when the server is reading its state from
    the external store.  The 'readData' is the first argument to all
    the callback functions.

    Read         execute a raw read of the store.  In binary mode, 'len'
                 bytes are read directly from the store.  In ASCII mode, up
                 to 'len' bytes of the current line are read from the
                 store, perhaps leaving more bytes to be read later.  The
                 return value is the number of bytes read on the current
                 line (which may be zero), or -1 for end of data.

    ReadI1       read an array of integers of various types and formats,
    ReadI2       returning the number of integers successfully read.  In
    ReadI4       BINARY mode a sequence of 'n' single, double or quad bytes
    ReadU1       are read from the stream and interpreted as "big-endian"
    ReadU2       (Motorola) format words.  In ASCII mode, the numbers are
    ReadU4       read from the current line, in decimal for signed values
                 and in hexadecimal for unsigned values.

    ReadFP       read an array of floating point numbers from the store.
                 The return value is the number of values read.

    ReadStr      read a string from the store.  In ASCII mode double quotes
                 will be removed.

    ReadID       read an identifier token from the store.  In BINARY this is
                 just a four-byte code value, but in ASCII this in the string
                 token which will be matched with its longword code.

    FindBlk      read ahead looking for the next block.  The array of block
                 identifiers includes all the blocks that could be expected
                 and is terminated with a null ID code.  If a reconginized
                 block is found in the file, it's ID code is returned.  A
                 zero return indicates no more valid blocks.

    EndBlk       complete reading the current open block.

    Depth        return the current block nesting level, where zero means
                 we've entered no blocks.
  }
  PLWLoadState = ^TLWLoadState;
  TLWLoadState = record
    IOMode   : Integer;
    ReadData : Pointer;

    Read    : function
              (      Data       : Pointer      ;
                     Buffer     : PChar        ;
                     Length     : Integer      ) : Integer;

    ReadI1  : function
              (      Data       : Pointer      ;
                     Buffer     : PChar        ;
                     N          : Integer      ) : Integer;
    ReadI2  : function
              (      Data       : Pointer      ;
                     Buffer     : PSmallInt    ;
                     N          : Integer      ) : Integer;
    ReadI4  : function
              (      Data       : Pointer      ;
                     Buffer     : PInteger     ;
                     N          : Integer      ) : Integer;
    ReadU1  : function
              (      Data       : Pointer      ;
                     Buffer     : PByte        ;
                     N          : Integer      ) : Integer;
    ReadU2  : function
              (      Data       : Pointer      ;
                     Buffer     : PWord        ;
                     N          : Integer      ) : Integer;
    ReadU4  : function
              (      Data       : Pointer      ;
                     Buffer     : PCardinal    ;
                     N          : Integer      ) : Integer;
    ReadFP  : function
              (      Data       : Pointer      ;
                     Buffer     : PSingle      ;
                     N          : Integer      ) : Integer;
    ReadStr : function
              (      Data       : Pointer      ;
                     Buffer     : PChar        ;
                     Max        : Integer      ) : Integer;
    ReadID  : function
              (      Data       : Pointer      ;
               const BlockIdent : PLWBlockIdent) : TLWID  ;

    FindBlk : function
              (      Data       : Pointer      ;
               const BlockIdent : PLWBlockIdent) : TLWID  ;
    EndBlk  : procedure
              (      Data       : Pointer      ) ;
    Depth   : function
              (      Data       : Pointer      ) : Integer;
    ReadDP  : function
              (      Data       : Pointer      ;
                     Buffer     : PDouble      ;
                     N          : Integer      ) : Integer;
  end;

  PLWFileIOFuncs = ^TLWFileIOFuncs;
  TLWFileIOFuncs = record
    OpenSave  : function
                (const Name   : PChar       ;
                       IOMode : Integer     ) : PLWSaveState;
    CloseSave : procedure
                (      Save   : PLWSaveState) ;
    OpenLoad  : function
                (const Name   : PChar       ;
                       IOMode : Integer     ) : PLWLoadState;
    CloseLoad : procedure
                (      Load   : PLWLoadState) ;
  end;

implementation

end.

